package com.ideaaedi.zoo.example.springboot.sse.util;

import com.ideaaedi.commonds.constants.SymbolConstant;
import lombok.SneakyThrows;
import org.apache.commons.lang3.tuple.Pair;

import java.io.Serializable;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * SSE 相关id、key 处理工具类
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.0.0
 */
public final class SseUidUtil {
    
    /**
     * sse连接唯一标识（占位符以此为：用户id、连接唯一标识）
     */
    public static final String SSE_UUID_REDIS_PREFIX = "sse:demo:%s:%s";
    
    /**
     * 构建sseEmitter唯一标识
     *
     * @param userId 用户id
     * @param connectId 连接id（不能包含:）
     *
     * @return sseEmitter唯一标识（格式为：{用户id}:{连接id}）
     */
    public static String buildEmitterUuid(Serializable userId, String connectId) {
        if (connectId.contains(SymbolConstant.COLON)) {
            throw new IllegalArgumentException("connectId cannot contain ':'.");
        }
        return userId + SymbolConstant.COLON + connectId;
    }
    
    /**
     * 从sseEmitter中获取用户id、连接id
     *
     * @param emitterUuid sseEmitter唯一标识
     *
     * @return 左 - 用户id；右 - 连接id
     */
    public static Pair<Long, String> splitEmitterUuid(String emitterUuid) {
        try {
            String[] arr = emitterUuid.split(SymbolConstant.COLON);
            Long userId = Long.parseLong(arr[0]);
            String connectionId = arr[1];
            return Pair.of(userId, connectionId);
        } catch (Exception e) {
            throw new IllegalArgumentException("split emitter-uuid fail. curr emitterUuid -> " + emitterUuid, e);
        }
    }
    
    /**
     * 构建emitterUuid对应的redis key
     *
     * @param emitterUuid sse唯一标识
     *
     * @return emitterUuid对应的redis key
     */
    public static String buildEmitterUuidRedisKey(String emitterUuid) {
        Pair<Long, String> pair = splitEmitterUuid(emitterUuid);
        String userIdStr = String.valueOf(pair.getLeft());
        String connectionId = pair.getRight();
        return String.format(SSE_UUID_REDIS_PREFIX, userIdStr, connectionId);
    }
    
    /**
     * 解析emitterUuid对应的redis key，获取emitterUuid
     *
     * @param emitterUuidRedisKey emitterUuid对应的redis key
     *
     * @return emitterUuid
     */
    public static String obtainEmitterUuid(String emitterUuidRedisKey) {
        try {
            // 最后两个依次为 用户id、connectId
            String[] arr = emitterUuidRedisKey.split(SymbolConstant.COLON);
            int length = arr.length;
            String userId = arr[length - 2];
            String connectionId = arr[length - 1];
            return buildEmitterUuid(userId, connectionId);
        } catch (Exception e) {
            throw new IllegalArgumentException("parse emitter-uuid-redis-key fail. curr emitterUuidRedisKey -> " + emitterUuidRedisKey, e);
        }
    }
    
    /**
     * 测试
     */
    @SneakyThrows
    public static void main(String[] args) {
        String userId = "9527";
        String connectId = UUID.randomUUID().toString().split("-")[0];
        String emitterUuid = buildEmitterUuid(userId, connectId);
        System.err.printf("使用用户id（%s）和连接id（%s）构建emitterUuid：\t %s", userId, connectId, emitterUuid);
        System.err.println();
        System.err.println();
        TimeUnit.SECONDS.sleep(1);
        
        String emitterUuidRedisKey = buildEmitterUuidRedisKey(emitterUuid);
        System.err.println("emitterUuid 转 redisKey：\t" + emitterUuidRedisKey);
        System.err.println();
        TimeUnit.SECONDS.sleep(1);
        
        Pair<Long, String> pair = splitEmitterUuid(emitterUuid);
        System.err.printf("从emitterUuid（%s）中解析用户id和连接id：\t 用户id=%s，连接id=%s", emitterUuid, pair.getLeft(), pair.getRight());
        System.err.println();
        System.err.println();
        TimeUnit.SECONDS.sleep(1);
        
        System.err.println("redisKey 转 emitterUuid：\t" + obtainEmitterUuid(emitterUuidRedisKey));
    }
}
